#define _GNU_SOURCE
#include "daemon_sub_process.h"
#include "sys/reboot.h"
#include "sys/wait.h"

/**
 * @brief 子进程的初始化 
 * @param cmd 子进程的命令
 * @return sub_process_t*
 * 为子进程  创建一个结构体，填写相关的参数
 */
sub_process_t *daemono_sub_process_init(char *cmd) 
{
    sub_process_t *sub_process = (sub_process_t *)malloc(sizeof(sub_process_t));
    sub_process->pid=-1;
    sub_process->cmd = cmd;
    sub_process->failed_count=0;
    return sub_process;

}

/**
 * @brief 子进程监控和启动
 * @param sub_process 子进程结构体
 */
int daemon_sub_process_check_start(sub_process_t *sub_process)
{
    int status=0;
  //1 判断子进程 是否启动过 pid !=-1   是否还活着 waitpid !=-1  说明子进程正常直接返回0
   if(sub_process->pid !=-1 &&  waitpid(sub_process->pid ,&status,WNOHANG) !=-1)
   {
       return 0;
   }

  //2 获得子进程的结束状态 ，如果是非正常结束 failed_count++ 如果超过阈值 重启设备
   if(status!=0)
   {
        sub_process->failed_count++;
        if(sub_process->failed_count>=MAX_FAILED_COUNT)
        {   
            // reboot(RB_AUTOBOOT);
        }
   }

  //3  需要启动子进程 
         //   3.1 fork 
         pid_t pid = fork();
        //    3.2 if(pid==0)  execve  执行子进程应用程序 gateway app/ gateway ota 
        if(pid==0)
        {   char *cmd=GATEWAY_CMD_NAME;
            char *args[]={cmd, sub_process->cmd,NULL};
            int ret = execve(cmd,args,NULL);
             //  3.3  如果execve 执行失败  输出报错日志 _exit(EXIT_FAILURE) 
             if(ret==-1)
             {
                 perror("execve");
                 _exit(EXIT_FAILURE);
             } 

        }else 
        {
            sub_process->pid=pid;
        }
           
        return 0;
}


/**
 * @brief 子进程e结束
 * @param sub_process 子进程结构体
 */
void daemon_sub_process_exit(sub_process_t *sub_process)
{
    kill(sub_process->pid,SIGTERM);
    waitpid(sub_process->pid,NULL,0);
    free(sub_process);
}